package main.tool;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.github.shyiko.mysql.binlog.BinaryLogClient;
import com.github.shyiko.mysql.binlog.event.*;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.io.IOException;
import java.util.concurrent.TimeoutException;

@Component
@PropertySource(value = "classpath:application.yml")

public class BinlogListener {

    private static final Logger log = LogManager.getLogger(BinlogListener.class);

    @Value("${spring.datasource.url}")
    private String url;

    @Value("${spring.datasource.username}")
    private String username;
    @Value("${spring.datasource.password}")
    private String password;
    @Value("${spring.datasource.server-id}")
    private long serverId;
    private String host;
    private int port;

    @PostConstruct
    public void readFile() {
        if(StrUtil.isEmptyIfStr(url)){
            return;
        }
        int firstIndex = url.indexOf("//");
        int lastIndex = url.lastIndexOf("/");
        String[] splitUrl = url.substring(firstIndex + 2, lastIndex).split(":");
        host = splitUrl[0];
        port = NumberUtil.parseInt(splitUrl[1], 3306);
        // 监听
        BinaryLogClient client = new BinaryLogClient(host, port, username, password);
        client.setServerId(serverId);
        client.registerEventListener(event -> {
            EventData data = event.getData();
            if (null != data) {
                if (data instanceof TableMapEventData) {
                    TableMapEventData tableMapEventData = (TableMapEventData) data;
                    log.info("表名字\t:{},表id\t:{}", tableMapEventData.getTable(),tableMapEventData.getTableId());
                }
                if (data instanceof WriteRowsEventData) {
                    WriteRowsEventData rowsEventData = (WriteRowsEventData) data;
                    log.info("插入数据\t:表id{},影响列{},数据{}", rowsEventData.getTableId(), rowsEventData.getIncludedColumns(), rowsEventData.getRows());
                }
                if (data instanceof UpdateRowsEventData) {
                    UpdateRowsEventData updateRowsEventData = (UpdateRowsEventData) data;
                    log.info("更新数据\t:表id{},影响列{},更新前{},更新后{}", updateRowsEventData.getTableId(),
                            updateRowsEventData.getIncludedColumns(), updateRowsEventData.getIncludedColumnsBeforeUpdate(),
                            updateRowsEventData.getRows());
                }
                if (data instanceof DeleteRowsEventData) {
                    DeleteRowsEventData deleteRowsEventData = (DeleteRowsEventData) data;
                    log.info("删除数据\t:表id{},影响列{},数据{}", deleteRowsEventData.getTableId(), deleteRowsEventData.getIncludedColumns(), deleteRowsEventData.getRows());
                }
            }
        });
        try {
            client.connect(40000);
        } catch (IOException | TimeoutException e) {
            throw new RuntimeException("监听异常，停止运行"+e.getMessage());
        }
    }
}
